<?php
/**
 * 新手任务
 */

namespace App\Repositories\Task;

use App\Enums\TaskEnum;
use App\Exceptions\BasicException;
use App\Services\Tools\RedisService;
use Illuminate\Support\Facades\DB;

class NewPlayerTaskRepository
{
    public $moduleId;

    public $taskExpireTime;

    public function __construct()
    {
        $this->moduleId = TaskEnum::TASK_MODULE_NEW_PLAYER;
    }

    // 获取用户注册日期
    public function getUserRegisterDate($userId)
    {
        $userRegisterTime = RedisService::getUserRegTime($userId);
        if (!$userRegisterTime) {
            throw new BasicException(15004);
        }

        $userRegisterDate = date("Y-m-d", $userRegisterTime);

        return $userRegisterDate;
    }

    // 获取用户新手任务过期时间
    public function getTaskExpireTime($userId)
    {
        if ($this->taskExpireTime) {
            return $this->taskExpireTime;
        }

        $this->taskExpireTime = strtotime($this->getUserRegisterDate($userId) . " + " . TaskEnum::TASK_DELAY_DAY_NEW_PLAYER . " days") - 1;

        return $this->taskExpireTime;
    }

    // 新手任务是否处于激活状态
    public function isActive($userId)
    {
        $allTask = app("repo_task")->getUserTaskList($userId, $this->moduleId);

        return app("repo_task")->isModuleActive($this->moduleId) &&
            $this->getTaskExpireTime($userId) >= time() &&
            !empty($allTask) && count($allTask) > 0;
    }

    // 解析新手任务配置
    public function parseNewPlayerConfig($allTaskConfig, $userId)
    {
        $registerDate = $this->getUserRegisterDate($userId);
        $result       = [];
        foreach ($allTaskConfig as $taskConfig) {
            for ($day = 1; $day <= TaskEnum::TASK_SHOW_DAY_NEW_PLAYER; $day++) {
                if ($day == $taskConfig['open_day']) {
                    $insertFlag = true;
                } elseif (
                    $day > $taskConfig['open_day'] &&
                    $taskConfig['cycle_days'] > 0 &&
                    ($taskConfig['cycle_days'] == 1 || $day % $taskConfig['cycle_days'] == 1)
                ) {
                    $insertFlag = true;
                } else {
                    $insertFlag = false;
                }

                if ($insertFlag) {
                    if (!isset($result[$day])) {
                        $result[$day] = [
                            "summary_task_unique_id" => "",
                            "list"                   => []
                        ];
                    }

                    $uniqueId = md5($this->moduleId . $userId . $taskConfig['id'] . $day);

                    if ($taskConfig['type_id'] == TaskEnum::TASK_TYPE_NEW_PLAYER_SUMMARY) {
                        if ($result[$day]['summary_task_unique_id'] != $uniqueId) {
                            foreach ($result[$day]["list"] as $index => $item) {
                                if (
                                    $item['type_id'] != TaskEnum::TASK_TYPE_NEW_PLAYER_SUMMARY &&
                                    $item['type_id'] != TaskEnum::TASK_TYPE_GIFT_BAG_TYPE
                                ) {
                                    $result[$day]['list'][$index]['parent_unique_id'] = $uniqueId;
                                }
                            }
                        }

                        $result[$day]['summary_task_unique_id'] = $uniqueId;
                    }

                    if (
                        $taskConfig['type_id'] != TaskEnum::TASK_TYPE_NEW_PLAYER_SUMMARY &&
                        $taskConfig['type_id'] != TaskEnum::TASK_TYPE_GIFT_BAG_TYPE
                    ) {
                        $parentUniqueId = $result[$day]['summary_task_unique_id'];
                    } else {
                        $parentUniqueId = "";
                    }

                    $now                    = time();
                    $diffDay                = $day - 1;
                    $show_date              = date("Y-m-d", strtotime($registerDate . " +{$diffDay} days"));
                    $result[$day]['list'][] = [
                        "name"             => $taskConfig['name'],
                        "desc"             => $taskConfig['desc'],
                        "unique_id"        => $uniqueId,
                        "user_id"          => $userId,
                        "module_id"        => $this->moduleId,
                        "type_id"          => $taskConfig['type_id'],
                        "task_config_id"   => $taskConfig['id'],
                        "reward_id"        => $taskConfig['reward_id'],
                        "expire_time"      => $this->getTaskExpireTime($userId),
                        "target_limit"     => $taskConfig['target_limit'],
                        "parent_unique_id" => $parentUniqueId,
                        "extra_json"       => json_encode([
                            "show_day"  => $day,
                            "show_date" => $show_date
                        ]),
                        "status"           => TaskEnum::TASK_USER_UN_FINISH,
                        "is_deleted"       => 0,
                        "reward_number"    => $taskConfig['reward_number'],
                        "reward_type"      => $taskConfig['reward_type'],
                        "add_time"         => $now,
                        "update_time"      => $now,
                    ];
                }
            }
        }

        return $result;
    }

    // 格式化新手任务
    public function formatNewPlayerTaskFromConfig($userId)
    {
        $allTaskConfig = app("repo_task")->getAllTaskConfig($this->moduleId);

        $userTaskMap = $this->parseNewPlayerConfig($allTaskConfig, $userId);
        if (!$userTaskMap) {
            return [];
        }

        $result = [];
        foreach ($userTaskMap as $day => $item) {
            $result = array_merge($result, $item['list']);
        }

        $result = array_values($result);

        return $result;
    }

    // 下发新手任务
    public function issueTask($userId)
    {
        $insertArr = $this->formatNewPlayerTaskFromConfig($userId);
        if (!$insertArr) {
            return true;
        }

        DB::connection("mysql")->transaction(function () use ($insertArr, $userId) {
            // 将已经发放过的任务都置为删除
            app("model_task_user")->where([
                "user_id"   => $userId,
                "module_id" => $this->moduleId,
            ])->update([
                "update_time" => time(),
                "is_deleted"  => 1,
            ]);

            // 发放任务
            $affectRows = DB::connection("mysql")->table(app('model_task_user')->getTable())->insert($insertArr);

            if (!$affectRows) {
                throw new BasicException(15005);
            }
        }, 5);

        return true;
    }

    // 获得用户的每日任务列表
    public function getUserTaskListByDate($userId, $date)
    {
        $result  = [
            "cur_day"            => 0,
            "top_days"           => [],
            "today_summary_task" => [],
            "list"               => [],
            "gift_bag_task"      => []
        ];
        $allTask = app("repo_task")->getUserTaskList($userId, $this->moduleId);
        if (empty($allTask)) {
            return $result;
        }

        $randomHolderId = app("repo_room")->getRandomHolderId();
        $userRoom       = app('model_user_room')->where("user_id", $userId)->first();

        $giftBagTask      = [];
        $todaySummaryTask = [];
        $todayTask        = [];
        $statusOriginMap  = [];
        foreach ($allTask as $userTask) {
            $showDate = $userTask->extra_data['show_date'] ?? "";

            if ($userTask->type_id == TaskEnum::TASK_TYPE_GIFT_BAG_TYPE) {
                $giftBagTask = $this->formatUserTask($userTask, $randomHolderId, $userRoom);;
            } elseif ($userTask->type_id == TaskEnum::TASK_TYPE_NEW_PLAYER_SUMMARY) {
                if ($showDate == $date) {
                    $todaySummaryTask = $this->formatUserTask($userTask, $randomHolderId, $userRoom);;
                }
            } else {
                if ($showDate == $date) {
                    $todayTask[] = $this->formatUserTask($userTask, $randomHolderId, $userRoom);
                }
            }

            if ($showDate && $userTask->type_id != TaskEnum::TASK_TYPE_GIFT_BAG_TYPE) {
                if (!isset($statusOriginMap[$showDate])) {
                    $statusOriginMap[$showDate] = [$userTask->status];
                } else {
                    $statusOriginMap[$showDate][] = $userTask->status;
                }
            }
        }

        $today   = date("Y-m-d");
        $userMap = [];
        foreach ($statusOriginMap as $dateItem => $statusList) {
            if ($dateItem > $today) {
                $userMap[$dateItem] = TaskEnum::TASK_NEW_PLAYER_DAILY_STATUS_CLOSE;
            } else {
                $temp = TaskEnum::TASK_NEW_PLAYER_DAILY_STATUS_OPEN;
                $flag = true;
                foreach ($statusList as $status) {
                    if ($status == TaskEnum::TASK_USER_HAS_FINISH) {
                        $flag = false;
                        $temp = TaskEnum::TASK_NEW_PLAYER_DAILY_STATUS_CAN_GET;
                        break;
                    } elseif ($status == TaskEnum::TASK_USER_UN_FINISH) {
                        $flag = false;
                    }
                }

                if ($flag) {
                    $temp = TaskEnum::TASK_NEW_PLAYER_DAILY_STATUS_ALL_GET;
                }

                $userMap[$dateItem] = $temp;
            }
        }

        $registerDate = $this->getUserRegisterDate($userId);
        $dayData      = [];
        $curDay       = 0;

        for ($day = 1; $day <= TaskEnum::TASK_SHOW_DAY_NEW_PLAYER; $day++) {
            $diffDay   = $day - 1;
            $show_date = date("Y-m-d", strtotime($registerDate . " +{$diffDay} days"));
            if ($date == $show_date) {
                $curDay = $day;
            }
            $dayData[] = [
                "day"    => $day,
                "date"   => $show_date,
                "status" => $userMap[$show_date]
            ];
        }

        $result["cur_day"]            = $curDay;
        $result["top_days"]           = $dayData;
        $result["today_summary_task"] = $todaySummaryTask;
        $result["list"]               = $todayTask;
        $result["gift_bag_task"]      = $giftBagTask;
        return $result;
    }

    // 格式化返回任务
    public function formatUserTask($userTask, $randomHolderId, $userRoom)
    {
        $linkData = app("repo_task")->getLinkDataFromTask($userTask, $randomHolderId, $userRoom);
        $current  = $userTask->task_degree;
        $target   = $userTask->target_limit;
        if (in_array($userTask->type_id, [
            TaskEnum::TASK_TYPE_RECHARGE_MONEY,
            TaskEnum::TASK_TYPE_RECHARGE_DAILY_MONEY
        ])) {
            $current = sprintf("%.2f", $current / TaskEnum::TASK_RATIO);
            $target  = sprintf("%.2f", $target / TaskEnum::TASK_RATIO);
        }
        return [
            "task_id"     => $userTask->id,
            "task_name"   => $userTask->name,
            "current"     => $current,
            "target"      => $target,
            "type_id"     => $userTask->type_id,
            "task_desc"   => $userTask->desc,
            "link_type"   => $linkData['link_type'],
            "link_param"  => $linkData['link_param'],
            "task_status" => $userTask->status,
            "reward"      => app("repo_task")->getRewardDataFromTask($userTask),
        ];
    }


}
